home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / cyberxxxsrc / decoder / txt / decodeqtrle.c < prev    next >
C/C++ Source or Header  |  1999-02-08  |  17KB  |  801 lines

  1. /*
  2. sc:c/sc opt txt/DecodeQTRLE.c
  3. */
  4.  
  5. #include "Decode.h"
  6. #include "YUV.h"
  7. #include "Utils.h"
  8.  
  9. struct QTRLEData {
  10.   uchar gray;
  11.   uchar *rngLimit;
  12.   struct RGBTriple *cmap;
  13. };
  14.  
  15. /* /// "DecodeQTRLE1()" */
  16. __asm void DecodeQTRLE1(REG(a0) uchar *from,
  17.                         REG(a1) uchar *to,
  18.                         REG(d0) ulong width,
  19.                         REG(d1) ulong height,
  20.                         REG(d2) ulong encSize,
  21.                         REG(a2) uchar *spec)
  22. {
  23.   long x, y, lines, d;
  24.  
  25.   if (encSize<8) return;
  26.   from+=4;
  27.   d=get16(from);
  28.   if (d & 0x0008) {
  29.     y=get16(from);
  30.     from+=2;
  31.     lines=get16(from);
  32.     from+=2;
  33.   } else {
  34.     y=0;
  35.     lines=height;
  36.   }
  37.   x=0;
  38.   y--;
  39.   lines++;
  40.   while (lines) {
  41.     ulong xskip, cnt;
  42.     uchar *iptr;
  43.     xskip=*from++;
  44.     cnt=*from++;
  45.     if (cnt==0) break;
  46.     if ((xskip==0x80) & (cnt==0x00)) {
  47.       lines=0;
  48.       y++;
  49.       x=0;
  50.     } else if ((xskip==0x80) && (cnt==0xff)) {
  51.       lines--;
  52.       y++;
  53.       x=0;
  54.     } else {
  55.       if (xskip & 0x80) {
  56.         lines--;
  57.         y++;
  58.         x=xskip & 0x7f;
  59.       } else {
  60.         x+=xskip;
  61.       }
  62.       iptr=to+(y*width)+(x<<4);
  63.       if (cnt<0x80) {
  64.         x+=cnt;
  65.         while(cnt--) {
  66.           ulong i, mask;
  67.           d=get16(from);
  68.           mask=0x8000;
  69.           for (i=0; i<16; i++) {
  70.             *iptr++=(d & mask) ? 0 : 1;
  71.             mask>>=1;
  72.           }
  73.         }
  74.       } else {
  75.         cnt=0x100-cnt;
  76.         x+=cnt;
  77.         d=get16(from);
  78.         while (cnt--) {
  79.           ulong i, mask;
  80.           mask=0x8000;
  81.           for (i=0; i<16; i++) {
  82.             *iptr++=(d & mask) ? 0 : 1;
  83.             mask>>=1;
  84.           }
  85.         }
  86.       }
  87.     }
  88.   }
  89. }
  90. /* \\\ */
  91.  
  92. /* /// "DecodeQTRLE4()" */
  93. __asm void DecodeQTRLE4(REG(a0) uchar *from,
  94.                         REG(a1) uchar *to,
  95.                         REG(d0) ulong width,
  96.                         REG(d1) ulong height,
  97.                         REG(d2) ulong encSize,
  98.                         REG(a2) uchar *spec)
  99. {
  100.   long x, y, lines, d;
  101.  
  102.   if (encSize<8) return;
  103.   from+=4;
  104.   d=get16(from);
  105.   if (d & 0x0008) {
  106.     y=get16(from);
  107.     from+=2;
  108.     lines=get16(from);
  109.     from+=2;
  110.   } else {
  111.     y=0;
  112.     lines=height;
  113.   }
  114.   x=-1;
  115.   while (lines) {
  116.     ulong xskip, cnt;
  117.     if (x==-1) {
  118.       xskip=*from++;
  119.       if (xskip==0) break;
  120.     } else {
  121.       xskip=0;
  122.     }
  123.     cnt=*from++;
  124.     if (cnt==0x00) {
  125.       lines=0;
  126.       y++;
  127.       x=-1;
  128.     } else if (cnt==0xff) {
  129.       lines--;
  130.       y++;
  131.       x=-1;
  132.     } else {
  133.       uchar *iptr;
  134.       if (xskip & 0x80) {
  135.         lines--;
  136.         y++;
  137.         x=xskip & 0x7f;
  138.       } else {
  139.         x+=xskip;
  140.       }
  141.       iptr=to+(y*width)+(x<<3);
  142.       if (cnt<0x80) {
  143.         x+=cnt;
  144.         while (cnt--) {
  145.           ulong i, shift, d0;
  146.           d0=get32(from);
  147.           shift=32;
  148.           for (i=0; i<8; i++) {
  149.             shift-=4;
  150.             *iptr++=(d0>>shift) & 0x0f;
  151.           }
  152.         }
  153.       } else {
  154.         ulong d0;
  155.         cnt=0x100-cnt;
  156.         d0=get32(from);
  157.         while (cnt--) {
  158.           ulong i, shift;
  159.           shift=32;
  160.           for (i=0; i<8; i++) {
  161.             shift-=4;
  162.             *iptr++=(d0>>shift) & 0x0f;
  163.           }
  164.         }
  165.       }
  166.     }
  167.   }
  168. }
  169. /* \\\ */
  170.  
  171. /* /// "DecodeQTRLE8()" */
  172. __asm void DecodeQTRLE8(REG(a0) uchar *from,
  173.                         REG(a1) uchar *to,
  174.                         REG(d0) ulong width,
  175.                         REG(d1) ulong height,
  176.                         REG(d2) ulong encSize,
  177.                         REG(a2) uchar *spec)
  178. {
  179.   long y, lines, d;
  180.  
  181.   if (encSize<8) return;
  182.   from+=4;
  183.   d=get16(from);
  184.   if (d & 0x0008) {
  185.     y=get16(from);
  186.     from+=2;
  187.     lines=get16(from);
  188.     from+=2;
  189.   } else {
  190.     y=0;
  191.     lines=height;
  192.   }
  193.  
  194.   while (lines--) {
  195.     ulong xskip, cnt;
  196.     uchar *iptr;
  197.     xskip=*from++;
  198.     if (xskip==0) break;
  199.     cnt=*from++;
  200.     iptr=to+(y*width)+4*(xskip-1);
  201.     while (cnt!=0xff) {
  202.       if (cnt==0x00) {
  203.         xskip=*from++;
  204.         iptr+=4*(xskip-1);
  205.       } else if (cnt<0x80) {
  206.         cnt*=4;
  207.         while (cnt--) *iptr++=*from++;
  208.       } else {
  209.         uchar d1, d2, d3, d4;
  210.         cnt=0x100-cnt;
  211.         d1=from[0];
  212.         d2=from[1];
  213.         d3=from[2];
  214.         d4=from[3];
  215.         from+=4;
  216.         while (cnt--) {
  217.           iptr[0]=d1;
  218.           iptr[1]=d2;
  219.           iptr[2]=d3;
  220.           iptr[3]=d4;
  221.           iptr+=4;
  222.         }
  223.       }
  224.       cnt=*from++;
  225.     }
  226.     y++;
  227.   }
  228. }
  229. /* \\\ */
  230.  
  231. /* /// "DecodeQTRLE16toRGB()" */
  232. __asm void DecodeQTRLE16toRGB(REG(a0) uchar *from,
  233.                               REG(a1) uchar *to,
  234.                               REG(d0) ulong width,
  235.                               REG(d1) ulong height,
  236.                               REG(d2) ulong encSize,
  237.                               REG(a2) uchar *spec)
  238. {
  239.   long y, lines, d;
  240.   uchar r, g, b;
  241.  
  242.   if (encSize<8) return;
  243.   from+=4;
  244.   d=get16(from);
  245.   if (d & 0x0008) {
  246.     y=get16(from);
  247.     from+=2;
  248.     lines=get16(from);
  249.     from+=2;
  250.   } else {
  251.     y=0;
  252.     lines=height;
  253.   }
  254.   while (lines--) {
  255.     ulong d, xskip, cnt;
  256.     uchar *iptr;
  257.     xskip=*from++;
  258.     if (xskip==0) break;
  259.     cnt=*from++;
  260.     iptr=to+(y*width+xskip-1)*3;
  261.     while (cnt!=0xff) {
  262.       if (cnt==0x00) {
  263.         xskip=*from++;
  264.         iptr+=3*(xskip-1);
  265.       } else if (cnt<0x80) {
  266.         while (cnt--) {
  267.           d=get16(from);
  268.           ColorToRGB(d,r,g,b);
  269.           iptr[0]=r;
  270.           iptr[1]=g;
  271.           iptr[2]=b;
  272.           iptr+=3;
  273.         }
  274.       } else {
  275.         cnt=0x100-cnt;
  276.         d=get16(from);
  277.         ColorToRGB(d,r,g,b);
  278.         while (cnt--) {
  279.           iptr[0]=r;
  280.           iptr[1]=g;
  281.           iptr[2]=b;
  282.           iptr+=3;
  283.         }
  284.       }
  285.       cnt=*from++;
  286.     }
  287.     y++;
  288.   }
  289. }
  290. /* \\\ */
  291.  
  292. /* /// "DecodeQTRLE16to332()" */
  293. __asm void DecodeQTRLE16to332(REG(a0) uchar *from,
  294.                               REG(a1) uchar *to,
  295.                               REG(d0) ulong width,
  296.                               REG(d1) ulong height,
  297.                               REG(d2) ulong encSize,
  298.                               REG(a2) struct QTRLEData *spec)
  299. {
  300.   long y, lines, d;
  301.   uchar gray=spec->gray;
  302.  
  303.   if (encSize<8) return;
  304.   from+=4;
  305.   d=get16(from);
  306.   if (d & 0x0008) {
  307.     y=get16(from);
  308.     from+=2;
  309.     lines=get16(from);
  310.     from+=2;
  311.   } else {
  312.     y=0;
  313.     lines=height;
  314.   }
  315.   while (lines--) {
  316.     ulong d, xskip, cnt;
  317.     uchar *iptr;
  318.     xskip=*from++;
  319.     if (xskip==0) break;
  320.     cnt=*from++;
  321.     iptr=to+(y*width+xskip-1);
  322.     while (cnt!=0xff) {
  323.       if (cnt==0x00) {
  324.         xskip=*from++;
  325.         iptr+=(xskip-1);
  326.       } else if (cnt<0x80) {
  327.         if (gray) {
  328.           while (cnt--) {
  329.             d=get16(from);
  330.             ColorTo332Gray(d,*iptr++);
  331.           }
  332.         } else {
  333.           while (cnt--) {
  334.             d=get16(from);
  335.             ColorTo332(d,*iptr++);
  336.           }
  337.         }
  338.       } else {
  339.         cnt=0x100-cnt;
  340.         d=get16(from);
  341.         if (gray) {ColorTo332Gray(d,d);} else {ColorTo332(d,d);}
  342.         while (cnt--) *iptr++=d;
  343.       }
  344.       cnt=*from++;
  345.     }
  346.     y++;
  347.   }
  348. }
  349. /* \\\ */
  350.  
  351. /* /// "DecodeQTRLE16to332Dith()" */
  352. __asm void DecodeQTRLE16to332Dith(REG(a0) uchar *from,
  353.                                   REG(a1) uchar *to,
  354.                                   REG(d0) ulong width,
  355.                                   REG(d1) ulong height,
  356.                                   REG(d2) ulong encSize,
  357.                                   REG(a2) struct QTRLEData *spec)
  358. {
  359.   long y, lines, d;
  360.   uchar *rngLimit=spec->rngLimit;
  361.   struct RGBTriple *cmap=spec->cmap;
  362.  
  363.   if (encSize<8) return;
  364.   from+=4;
  365.   d=get16(from);
  366.   if (d & 0x0008) {
  367.     y=get16(from);
  368.     from+=2;
  369.     lines=get16(from);
  370.     from+=2;
  371.   } else {
  372.     y=0;
  373.     lines=height;
  374.   }
  375.   while (lines--) {
  376.     ulong d, xskip, cnt;
  377.     uchar *iptr;
  378.     ulong r, g, b, color;
  379.     long re=0, ge=0, be=0;
  380.     xskip=*from++;
  381.     if (xskip==0) break;
  382.     cnt=*from++;
  383.     iptr=to+(y*width+xskip-1);
  384.     while (cnt!=0xff) {
  385.       if (cnt==0x00) {
  386.         xskip=*from++;
  387.         iptr+=(xskip-1);
  388.       } else if (cnt<0x80) {
  389.         while (cnt--) {
  390.           d=get16(from);
  391.           ColorToRGB(d,r,g,b);
  392.           DitherGetRGB(r,g,b,re,ge,be,color);
  393.           *iptr++=color;
  394.         }
  395.       } else {
  396.         cnt=0x100-cnt;
  397.         d=get16(from);
  398.         ColorToRGB(d,r,g,b);
  399.         while (cnt--) {
  400.           DitherGetRGB(r,g,b,re,ge,be,color);
  401.           *iptr++=color;
  402.         }
  403.       }
  404.       cnt=*from++;
  405.     }
  406.     y++;
  407.   }
  408. }
  409. /* \\\ */
  410.  
  411. /* /// "DecodeQTRLE24toRGB()" */
  412. __asm void DecodeQTRLE24toRGB(REG(a0) uchar *from,
  413.                               REG(a1) uchar *to,
  414.                               REG(d0) ulong width,
  415.                               REG(d1) ulong height,
  416.                               REG(d2) ulong encSize,
  417.                               REG(a2) uchar *spec)
  418. {
  419.   long y, lines, d;
  420.   uchar r, g, b;
  421.  
  422.   if (encSize<8) return;
  423.   from+=4;
  424.   d=get16(from);
  425.   if (d & 0x0008) {
  426.     y=get16(from);
  427.     from+=2;
  428.     lines=get16(from);
  429.     from+=2;
  430.   } else {
  431.     y=0;
  432.     lines=height;
  433.   }
  434.   while (lines--) {
  435.     ulong xskip, cnt;
  436.     uchar *iptr;
  437.     xskip=*from++;
  438.     if (xskip==0) break;
  439.     cnt=*from++;
  440.     iptr=to+(y*width+xskip-1)*3;
  441.     while (cnt!=0xff) {
  442.       if (cnt==0x00) {
  443.         xskip=*from++;
  444.         iptr+=3*(xskip-1);
  445.       } else if (cnt<0x80) {
  446.         while (cnt--) {
  447.           iptr[0]=from[0]; /* r */
  448.           iptr[1]=from[1]; /* g */
  449.           iptr[2]=from[2]; /* b */
  450.           iptr+=3;
  451.           from+=3;
  452.         }
  453.       } else {
  454.         cnt=0x100-cnt;
  455.         r=from[0];
  456.         g=from[1];
  457.         b=from[2];
  458.         from+=3;
  459.         while (cnt--) {
  460.           iptr[0]=r;
  461.           iptr[1]=g;
  462.           iptr[2]=b;
  463.           iptr+=3;
  464.         }
  465.       }
  466.       cnt=*from++;
  467.     }
  468.     y++;
  469.   }
  470. }
  471. /* \\\ */
  472.  
  473. /* /// "DecodeQTRLE24to332()" */
  474. __asm void DecodeQTRLE24to332(REG(a0) uchar *from,
  475.                               REG(a1) uchar *to,
  476.                               REG(d0) ulong width,
  477.                               REG(d1) ulong height,
  478.                               REG(d2) ulong encSize,
  479.                               REG(a2) struct QTRLEData *spec)
  480. {
  481.   long y, lines, d;
  482.   uchar r, g, b;
  483.   uchar gray=spec->gray;
  484.  
  485.   if (encSize<8) return;
  486.   from+=4;
  487.   d=get16(from);
  488.   if (d & 0x0008) {
  489.     y=get16(from);
  490.     from+=2;
  491.     lines=get16(from);
  492.     from+=2;
  493.   } else {
  494.     y=0;
  495.     lines=height;
  496.   }
  497.   while (lines--) {
  498.     ulong d, xskip, cnt;
  499.     uchar *iptr;
  500.     xskip=*from++;
  501.     if (xskip==0) break;
  502.     cnt=*from++;
  503.     iptr=to+(y*width+xskip-1);
  504.     while (cnt!=0xff) {
  505.       if (cnt==0x00) {
  506.         xskip=*from++;
  507.         iptr+=(xskip-1);
  508.       } else if (cnt<0x80) {
  509.         if (gray) {
  510.           while (cnt--) {
  511.             r=from[0];
  512.             g=from[1];
  513.             b=from[2];
  514.             from+=3;
  515.             *iptr++=RGB8toGray(r,g,b);
  516.           }
  517.         } else {
  518.           while (cnt--) {
  519.             r=from[0];
  520.             g=from[1];
  521.             b=from[2];
  522.             from+=3;
  523.             *iptr++=RGBto332(r,g,b,scale8);
  524.           }
  525.         }
  526.       } else {
  527.         cnt=0x100-cnt;
  528.         r=from[0];
  529.         g=from[1];
  530.         b=from[2];
  531.         from+=3;
  532.         d=(gray) ? RGB8toGray(r,g,b) : RGBto332(r,g,b,scale8);
  533.         while (cnt--) *iptr++=d;
  534.       }
  535.       cnt=*from++;
  536.     }
  537.     y++;
  538.   }
  539. }
  540. /* \\\ */
  541.  
  542. /* /// "DecodeQTRLE24to332Dith()" */
  543. __asm void DecodeQTRLE24to332Dith(REG(a0) uchar *from,
  544.                                   REG(a1) uchar *to,
  545.                                   REG(d0) ulong width,
  546.                                   REG(d1) ulong height,
  547.                                   REG(d2) ulong encSize,
  548.                                   REG(a2) struct QTRLEData *spec)
  549. {
  550.   long y, lines, d;
  551.   ulong r, g, b;
  552.   uchar *rngLimit=spec->rngLimit;
  553.   struct RGBTriple *cmap=spec->cmap;
  554.  
  555.   if (encSize<8) return;
  556.   from+=4;
  557.   d=get16(from);
  558.   if (d & 0x0008) {
  559.     y=get16(from);
  560.     from+=2;
  561.     lines=get16(from);
  562.     from+=2;
  563.   } else {
  564.     y=0;
  565.     lines=height;
  566.   }
  567.   while (lines--) {
  568.     ulong xskip, cnt, color;
  569.     uchar *iptr;
  570.     long re=0, ge=0, be=0;
  571.     xskip=*from++;
  572.     if (xskip==0) break;
  573.     cnt=*from++;
  574.     iptr=to+(y*width+xskip-1);
  575.     while (cnt!=0xff) {
  576.       if (cnt==0x00) {
  577.         xskip=*from++;
  578.         iptr+=(xskip-1);
  579.       } else if (cnt<0x80) {
  580.         while (cnt--) {
  581.           r=from[0];
  582.           g=from[1];
  583.           b=from[2];
  584.           from+=3;
  585.           DitherGetRGB(r,g,b,re,ge,be,color);
  586.           *iptr++=color;
  587.         }
  588.       } else {
  589.         cnt=0x100-cnt;
  590.         r=from[0];
  591.         g=from[1];
  592.         b=from[2];
  593.         from+=3;
  594.         while (cnt--) {
  595.           DitherGetRGB(r,g,b,re,ge,be,color);
  596.           *iptr++=color;
  597.         }
  598.       }
  599.       cnt=*from++;
  600.     }
  601.     y++;
  602.   }
  603. }
  604. /* \\\ */
  605.  
  606. /* /// "DecodeQTRLE32toRGB()" */
  607. __asm void DecodeQTRLE32toRGB(REG(a0) uchar *from,
  608.                               REG(a1) uchar *to,
  609.                               REG(d0) ulong width,
  610.                               REG(d1) ulong height,
  611.                               REG(d2) ulong encSize,
  612.                               REG(a2) uchar *spec)
  613. {
  614.   long y, lines, d;
  615.   uchar r, g, b;
  616.  
  617.   if (encSize<8) return;
  618.   from+=4;
  619.   d=get16(from);
  620.   if (d & 0x0008) {
  621.     y=get16(from);
  622.     from+=2;
  623.     lines=get16(from);
  624.     from+=2;
  625.   } else {
  626.     y=0;
  627.     lines=height;
  628.   }
  629.   while (lines--) {
  630.     ulong xskip, cnt;
  631.     uchar *iptr;
  632.     xskip=*from++;
  633.     if (xskip==0) break;
  634.     cnt=*from++;
  635.     iptr=to+(y*width+xskip-1)*3;
  636.     while (cnt!=0xff) {
  637.       if (cnt==0x00) {
  638.         xskip=*from++;
  639.         iptr+=3*(xskip-1);
  640.       } else if (cnt<0x80) {
  641.         while (cnt--) {
  642.           iptr[0]=from[1]; /* r */
  643.           iptr[1]=from[2]; /* g */
  644.           iptr[2]=from[3]; /* b */
  645.           iptr+=3;
  646.           from+=4;
  647.         }
  648.       } else {
  649.         cnt=0x100-cnt;
  650.         r=from[1];
  651.         g=from[2];
  652.         b=from[3];
  653.         from+=4;
  654.         while (cnt--) {
  655.           iptr[0]=r;
  656.           iptr[1]=g;
  657.           iptr[2]=b;
  658.           iptr+=3;
  659.         }
  660.       }
  661.       cnt=*from++;
  662.     }
  663.     y++;
  664.   }
  665. }
  666. /* \\\ */
  667.  
  668. /* /// "DecodeQTRLE32to332()" */
  669. __asm void DecodeQTRLE32to332(REG(a0) uchar *from,
  670.                               REG(a1) uchar *to,
  671.                               REG(d0) ulong width,
  672.                               REG(d1) ulong height,
  673.                               REG(d2) ulong encSize,
  674.                               REG(a2) struct QTRLEData *spec)
  675. {
  676.   long y, lines, d;
  677.   uchar r, g, b;
  678.   uchar gray=spec->gray;
  679.  
  680.   if (encSize<8) return;
  681.   from+=4;
  682.   d=get16(from);
  683.   if (d & 0x0008) {
  684.     y=get16(from);
  685.     from+=2;
  686.     lines=get16(from);
  687.     from+=2;
  688.   } else {
  689.     y=0;
  690.     lines=height;
  691.   }
  692.   while (lines--) {
  693.     ulong d, xskip, cnt;
  694.     uchar *iptr;
  695.     xskip=*from++;
  696.     if (xskip==0) break;
  697.     cnt=*from++;
  698.     iptr=to+(y*width+xskip-1);
  699.     while (cnt!=0xff) {
  700.       if (cnt==0x00) {
  701.         xskip=*from++;
  702.         iptr+=(xskip-1);
  703.       } else if (cnt<0x80) {
  704.         if (gray) {
  705.           while (cnt--) {
  706.             r=from[1];
  707.             g=from[2];
  708.             b=from[3];
  709.             from+=4;
  710.             *iptr++=RGB8toGray(r,g,b);
  711.           }
  712.         } else {
  713.           while (cnt--) {
  714.             r=from[1];
  715.             g=from[2];
  716.             b=from[3];
  717.             from+=4;
  718.             *iptr++=RGBto332(r,g,b,scale8);
  719.           }
  720.         }
  721.       } else {
  722.         cnt=0x100-cnt;
  723.         r=from[1];
  724.         g=from[2];
  725.         b=from[3];
  726.         from+=4;
  727.         d=(gray) ? RGB8toGray(r,g,b) : RGBto332(r,g,b,scale8);
  728.         while (cnt--) *iptr++=d;
  729.       }
  730.       cnt=*from++;
  731.     }
  732.     y++;
  733.   }
  734. }
  735. /* \\\ */
  736.  
  737. /* /// "DecodeQTRLE32to332Dith()" */
  738. __asm void DecodeQTRLE32to332Dith(REG(a0) uchar *from,
  739.                                   REG(a1) uchar *to,
  740.                                   REG(d0) ulong width,
  741.                                   REG(d1) ulong height,
  742.                                   REG(d2) ulong encSize,
  743.                                   REG(a2) struct QTRLEData *spec)
  744. {
  745.   long y, lines, d;
  746.   ulong r, g, b;
  747.   uchar *rngLimit=spec->rngLimit;
  748.   struct RGBTriple *cmap=spec->cmap;
  749.  
  750.   if (encSize<8) return;
  751.   from+=4;
  752.   d=get16(from);
  753.   if (d & 0x0008) {
  754.     y=get16(from);
  755.     from+=2;
  756.     lines=get16(from);
  757.     from+=2;
  758.   } else {
  759.     y=0;
  760.     lines=height;
  761.   }
  762.   while (lines--) {
  763.     ulong xskip, cnt, color;
  764.     uchar *iptr;
  765.     long re=0, ge=0, be=0;
  766.     xskip=*from++;
  767.     if (xskip==0) break;
  768.     cnt=*from++;
  769.     iptr=to+(y*width+xskip-1);
  770.     while (cnt!=0xff) {
  771.       if (cnt==0x00) {
  772.         xskip=*from++;
  773.         iptr+=(xskip-1);
  774.       } else if (cnt<0x80) {
  775.         while (cnt--) {
  776.           r=from[1];
  777.           g=from[2];
  778.           b=from[3];
  779.           from+=4;
  780.           DitherGetRGB(r,g,b,re,ge,be,color);
  781.           *iptr++=color;
  782.         }
  783.       } else {
  784.         cnt=0x100-cnt;
  785.         r=from[1];
  786.         g=from[2];
  787.         b=from[3];
  788.         from+=4;
  789.         while (cnt--) {
  790.           DitherGetRGB(r,g,b,re,ge,be,color);
  791.           *iptr++=color;
  792.         }
  793.       }
  794.       cnt=*from++;
  795.     }
  796.     y++;
  797.   }
  798. }
  799. /* \\\ */
  800.  
  801.